feat: definitive OpenRouter integration (v1.4 → v1.6)#11
Merged
Conversation
Three-version arc that turns the pipe into a comprehensive OpenRouter
client mapping the official Python/TypeScript SDK feature surface.
v1.4.0 — Full catalog visibility
- OUTPUT_MODALITIES valve: pass `output_modalities=all` to /models so TTS,
audio, image-output, and embedding models surface in the selector
(e.g. openai/gpt-4o-mini-tts-*, previously hidden)
- Provider icon auto-discovery: lazy-load /api/frontend/all-providers and
resolve icons for ~20 additional model authors (xAI, Inflection,
NVIDIA, Arcee, Morph, Cerebras, …) with hyphen-strip slug normalisation
- Recognise gstatic faviconV2 URLs in _is_owui_managed_icon
v1.5.0 — Routing capabilities (one breaking change)
- MODEL_VARIANTS: virtual :nitro/:exacto/:thinking/:online/:free/:extended
routing that inherits base name & icon
- Reasoning extras: minimal & xhigh effort levels, REASONING_SUMMARY_MODE
(auto/concise/detailed)
- Anthropic interleaved thinking (anthropic-beta header) and configurable
prompt-cache TTL (5m/1h)
- ZDR support: ZDR_MODELS_ONLY (filter via /endpoints/zdr) and ZDR_ENFORCE
(provider.zdr=true)
- TOOL_CALLING_FILTER trinary; FREE_ONLY → FREE_MODEL_FILTER
(all/only/exclude) — BREAKING
- HTTP_REFERER_OVERRIDE valve
v1.6.0 — SDK feature parity
- Web search plugin (5 valves): enable + max_results + custom prompt +
domain allow/deny lists; coexists with user-supplied plugins
- MODEL_CATEGORY: server-side ?category= filter
- Deprecation handling: ⚠ tag on expiration_date, optional hide
- REASONING_MAX_TOKENS budget cap
- Provider preferences extras: only / quantizations / allow_fallbacks /
max_price.{prompt,completion}
- SERVICE_TIER hint (auto/default/flex/priority/scale)
- SHOW_GENERATION_ID: surfaces gen-IDs from stream and non-stream paths
for /generation?id= audit lookups
- Cached prompt-token cost breakdown (Anthropic/OpenAI/Gemini caching)
Tests: 431 → 551 (+120 assertions covering each new code path).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the OpenRouter manifold pipe from v1.3.0 to v1.6.0, expanding it into a more comprehensive OpenRouter client with broader catalog visibility, additional routing/filtering valves, web search support, and improved audit/cost reporting.
Changes:
- Extends model catalog fetching/filtering (output modalities, category, free/tool/ZDR filters, deprecated model handling, model variants).
- Adds request/payload features (web search plugin injection, service tier hinting, expanded reasoning configuration, ZDR enforcement, Anthropic interleaved-thinking + cache TTL).
- Improves response metadata surfacing (generation ID footer, cached-token cost breakdown) and updates tests/docs accordingly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
openrouter_pipe.py |
Adds new valves/helpers and expands model listing, routing, headers, payload building, and response footers. |
test_pipe.py |
Adds/updates unit tests for new valves and behaviors; migrates FREE_ONLY references to FREE_MODEL_FILTER. |
integration_test.py |
Updates integration test to use FREE_MODEL_FILTER="only". |
README.md |
Updates feature list and configuration documentation for new v1.4–v1.6 capabilities. |
function.json |
Bumps manifest metadata (description/version) to 1.6.0. |
CHANGELOG.md |
Adds entries for v1.4.0–v1.6.0 describing new features and breaking change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+58
to
62
| - **Generation auditability** — optional generation ID footer maps each response to OpenRouter's `/generation?id=` activity API. | ||
| - **Cached-input savings** — surface cached vs. non-cached prompt tokens in the cost footer (Anthropic prompt caching, OpenAI implicit caching, Gemini context caching). | ||
| - **Deprecation visibility** — models with an `expiration_date` are tagged with ⚠ in the selector (or hidden via `HIDE_DEPRECATED_MODELS`). | ||
| - **Provider routing** — sort by `price`, `throughput`, or `latency`; prefer or exclude specific providers; enforce `require_parameters`. | ||
| - **Reasoning tokens** — `<think>` blocks streamed in real time with configurable effort (`low`, `medium`, `high`). |
| - **Provider icons** — 13 provider logos synced directly into Open WebUI's model database. | ||
| - **Provider icons** — 13 hardcoded fast-path logos plus auto-discovered icons for ~20 more providers (xAI, Inflection, NVIDIA, Arcee, Morph, Cerebras, …) lazy-loaded from OpenRouter's provider registry, all synced directly into Open WebUI's model database. | ||
| - **Retry logic** — exponential backoff with jitter on timeout and connection errors. | ||
| - **FREE_ONLY mode** — filter to show only free-tier models (`:free` suffix or `0/0` pricing). |
Comment on lines
113
to
120
| # Temporarily clear env vars that might interfere | ||
| _env_backup = {} | ||
| for k in [ | ||
| "OPENROUTER_API_KEY", "OPENROUTER_BASE_URL", | ||
| "OPENROUTER_REASONING_EFFORT", "OPENROUTER_INCLUDE_REASONING", | ||
| "OPENROUTER_MODEL_PROVIDERS", "OPENROUTER_INVERT_PROVIDER_LIST", | ||
| "OPENROUTER_FREE_ONLY", "OPENROUTER_PROVIDER_SORT", | ||
| "OPENROUTER_FREE_MODEL_FILTER", "OPENROUTER_PROVIDER_SORT", | ||
| "OPENROUTER_PROVIDER_ORDER", "OPENROUTER_PROVIDER_IGNORE", |
Comment on lines
1017
to
1021
| # 15b. FREE_ONLY filter | ||
| pipe.valves = Pipe.Valves(OPENROUTER_API_KEY="test-key", FREE_ONLY=True) | ||
| pipe.valves = Pipe.Valves(OPENROUTER_API_KEY="test-key", FREE_MODEL_FILTER="only") | ||
|
|
||
| # Mock data with pricing info: one :free suffix, one free-by-pricing, one paid | ||
| mock_models_pricing = { |
Comment on lines
+1294
to
+1295
| prefix_str = prefix or "" | ||
| # Strip the user-set prefix so we can reuse base names verbatim. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three-version arc that turns the pipe into a comprehensive OpenRouter client mapping the official Python/TypeScript SDK feature surface. Adds 24 new valves, two new helpers, server-side filtering, web search, deprecation handling, generation auditability, and cached-token cost breakdowns. One breaking change (
FREE_ONLY→FREE_MODEL_FILTER).Type of Change
Changes Made
v1.4.0 — Full catalog visibility
OUTPUT_MODALITIESvalve — passoutput_modalities=allto/modelsso TTS, audio, image-output, and embedding models surface in the selector (e.g.openai/gpt-4o-mini-tts-*, previously hidden by OpenRouter's text-only default)/api/frontend/all-providersand resolve icons for ~20 additional model authors (xAI, Inflection, NVIDIA, Arcee, Morph, Cerebras, …) with hyphen-strip slug normalisation_is_owui_managed_iconv1.5.0 — Routing capabilities
MODEL_VARIANTS— virtual:nitro/:exacto/:thinking/:online/:free/:extendedrouting that inherits base name & iconminimalandxhigheffort levels,REASONING_SUMMARY_MODE(auto/concise/detailed)anthropic-beta: interleaved-thinking-2025-05-14header foranthropic/*modelsZDR_MODELS_ONLY(catalog filter via/endpoints/zdr) andZDR_ENFORCE(provider.zdr=true)TOOL_CALLING_FILTERtrinaryHTTP_REFERER_OVERRIDEvalveFREE_ONLY(bool) →FREE_MODEL_FILTER(all/only/exclude)v1.6.0 — SDK feature parity
ENABLE_WEB_SEARCH,WEB_SEARCH_MAX_RESULTS,WEB_SEARCH_PROMPT,WEB_SEARCH_INCLUDE_DOMAINS,WEB_SEARCH_EXCLUDE_DOMAINS); coexists with user-supplied plugins without duplicationMODEL_CATEGORY— server-side?category=filter (programming, roleplay, marketing, science, …)expiration_date != nullmodels tagged⚠ {name} (deprecated); optionalHIDE_DEPRECATED_MODELSREASONING_MAX_TOKENS— hard cap (reasoning.max_tokens)PROVIDER_ONLY,PROVIDER_QUANTIZATIONS,PROVIDER_ALLOW_FALLBACKS,PROVIDER_MAX_PRICE_PROMPT,PROVIDER_MAX_PRICE_COMPLETIONSERVICE_TIER— auto/default/flex/priority/scaleSHOW_GENERATION_ID— capturesidfrom stream and non-stream chat paths so users can callGET /api/v1/generation?id=for auditsprompt_tokens_details.cached_tokens/cache_read_input_tokensrendered in theSHOW_COST_INFOfooter (Anthropic/OpenAI/Gemini caching)Testing
python test_pipe.py— 551/551 ✓, was 431)python integration_test.py) — not run locally (requires realOPENROUTER_API_KEY);FREE_ONLYreferences migrated toFREE_MODEL_FILTERCHANGELOG.mdupdated with v1.4.0, v1.5.0, v1.6.0 entriesMigration notes
Single breaking change: setups using
FREE_ONLY=truemust switch toFREE_MODEL_FILTER=only.FREE_ONLY=false(the default) needs no change. All other v1.4–v1.6 valves are backwards-compatible (defaults preserve prior behaviour) exceptOUTPUT_MODALITIESwhose defaultalldeliberately widens the catalog.Out of scope (deferred)
/api/v1/responsesendpoint (needs request/response/streaming rewrite)Checklist
printstatements beyond[OpenRouter Pipe]logging🤖 Generated with Claude Code